Skip to content

GH-2890: Document a bridge for subflow starts #3040

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

artembilan
Copy link
Member

Fixes #2890

Explain in a docs why and how a bridge appears in the flow when we
declare a subflow for mapping

Fixes spring-projects#2890

Explain in a docs why and how a `bridge` appears in the flow when we
declare a subflow for mapping
@@ -816,6 +816,11 @@ When you configure a sub-flow as a lambda, the framework handles the request-rep
Sub-flows can be nested to any depth, but we do not recommend doing so.
In fact, even in the router case, adding complex sub-flows within a flow would quickly begin to look like a plate of spaghetti and be difficult for a human to parse.

NOTE: Any sub-flow mappings end up with a `MessageChannel` connection between an original component as a producer (e.g. a `discardChannel` in the `MessageFilter`) and the first endpoint in the sub-flow as a consumer.
When sub-flow is started with a channel, an extra `bridge()` is placed between the mapping channel and this one to make the proper flow wiring.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace this sentence with:

When a sub-flow is explicitly configured with a channel() as the first element, the framework implicitly places a bridge() between the flow's input channel and that channel.

@@ -816,6 +816,11 @@ When you configure a sub-flow as a lambda, the framework handles the request-rep
Sub-flows can be nested to any depth, but we do not recommend doing so.
In fact, even in the router case, adding complex sub-flows within a flow would quickly begin to look like a plate of spaghetti and be difficult for a human to parse.

NOTE: Any sub-flow mappings end up with a `MessageChannel` connection between an original component as a producer (e.g. a `discardChannel` in the `MessageFilter`) and the first endpoint in the sub-flow as a consumer.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am having trouble parsing this sentence. I can reword it if I understood what you are trying to say. Perhaps if you can provide an example flow, I can try to reword it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I want to say here that sub-flow's firs consumer is a subscriber to the channel to which original component is producing.
Imaging we have a filter with its discardChannel. There definitely should be something subscribing to that channel and, well, frankly we always call that as a sub-flow.
In case of DSL we just don't mention that channel in between explicitly to avoid boilerplate code, but it is there anyway by the framework. Just because the mentioned filter really expects from us a MessageChannel for its discardChannel option. So, or we use an inputChannel of the IntegrationFlow bean you provide for the sub-flow or we create a new one and start sub-flow from it letting that filter to produce to this channel when it discards messages.

Hope this is getting cleaner...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear what a subflow has to do with a filter's discard channel; perhaps a DSL snippet will help me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, what I mean is like this:

.filter(p -> p instanceof String, e -> e
	.discardFlow(df -> ...))

where that sub-flow is connected to an internally created discardChannel for the MessageFilter.
That's the point where that bridge() comes to the scene when you try to use an explicit channel() in the beginning of that flow.
Just because there is already a channel - created by the framework and we can't determine this explicit channel() because this sub-flow has not been parsed yet, unlike externally configured @Bean IntegrationFlow.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. My confusion was because you said discardChannel, not discardFlow.

How about...

In cases where the DSL supports a subflow configuration, where a channel is normally needed for the component being configured, and that subflow starts with a channel() element, the framework implicitly places a bridge() between the flow's input channel and that channel.

For example, in...

.filter(p -> p instanceof String, e -> e
	.discardFlow(df -> df
                         .channel(MessageChannels.queue())
                         ...)
...

... the framework can't wire a subflow into a filter, so a discardChannel bean is created and bridged to the queue channel at the start of the subflow.

@@ -816,6 +816,11 @@ When you configure a sub-flow as a lambda, the framework handles the request-rep
Sub-flows can be nested to any depth, but we do not recommend doing so.
In fact, even in the router case, adding complex sub-flows within a flow would quickly begin to look like a plate of spaghetti and be difficult for a human to parse.

NOTE: Any sub-flow mappings end up with a `MessageChannel` connection between an original component as a producer (e.g. a `discardChannel` in the `MessageFilter`) and the first endpoint in the sub-flow as a consumer.
When sub-flow is started with a channel, an extra `bridge()` is placed between the mapping channel and this one to make the proper flow wiring.
When an existing `IntegrationFlow` bean is used as a subflow reference, there is no such a bridge in between since the framework can resolve the first channel from the flow bean.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no such bridge

@artembilan
Copy link
Member Author

Pushed some doc fix.

Thanks

@garyrussell
Copy link
Contributor

Merged as 5b43b6c with minor polishing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Explain the need for an initial bridge in a subflow starting with a channel
2 participants